use std::error::Error;
use std::fs;
use std::env;


pub fn read(config: Config) -> Result<(), Box<dyn Error>> {
    let content = fs::read_to_string(config.fileName)?;


    let insensitive = config.insensitive;

    let res;
    if insensitive {
        res = search(&config.query, &content);
    } else {
        res = search_case_insensitive(&config.query, &content);
    }


    println!("res is {:?}", res);

    Ok(())
}

pub struct Config {
    pub query: String,
    pub fileName: String,
    pub insensitive: bool,
}


impl Config {
    pub fn new(args: &[String]) -> Result<Config, String> {
        if args.len() < 3 {
            return Err("参数不正确！！！！".to_string());
        }

        // 获取环境变量
        let case_insensitive = env::var("CASE_INSENSITIVE").is_err();
        Ok(Config {
            query: args[1].clone(),
            fileName: args[2].clone(),
            insensitive: case_insensitive,
        })
    }
}


pub fn search<'a>(p0: &str, p1: &'a str) -> Vec<&'a str> {
    let mut v = Vec::new();

    for line in p1.lines() {
        if line.contains(p0) {
            v.push(line)
        }
    }

    v
}

//不区分大小写
pub fn search_case_insensitive<'a>(p0: &str, p1: &'a str) -> Vec<&'a str> {
    let mut v = Vec::new();

    let query = p0.to_lowercase();

    // let con = p1.to_lowercase();

    for line in p1.lines() {
        if line.to_lowercase().contains(&query) {
            v.push(line)
        }
    }

    v
}


#[cfg(test)]
mod tests {
    use crate::{search, search_case_insensitive};

    #[test]
    fn one_res() {
        let query = "safe";


        let content = "\
        Rust
safe , fast , productive .
Pick three
        ";


        assert_eq!(vec!["safe , fast , productive ."], search(query, content))
    }


    #[test]
    // 区分大小写
    fn one_res2() {
        let query = "rust";


        let content = "\
        Rust
safe , fast , productive .
Pick three
Duct
        ";

        let res = search_case_insensitive(query, content);

        assert_eq!(vec!["Rust"], res);
    }
}

